# Build the whole project.
#
C	= gcc
CXX	= g++

# These two directories can be multiple.
LIB_DIR		= ./lib
INC_DIR		= ./include
# Only one value is allowed.
OBJ_DIR		= ./bin
SRC_DIR		= ./src
SO_DIR		= ./module
TMPL_DIR	= ./template

# Avoid the key word, I add '_' as prefix.
LD		= $(foreach _dir, $(LIB_DIR), -L$(_dir))
INC		= $(foreach inc, $(INC_DIR), -I$(inc))

LIB_FILE	= $(wildcard $(LIB)/*.a)
LIB_FILE	+= $(wildcard $(LIB)/*.so)

INC_FILE	=
LD_FILE		= dl rt
INC_FLAG	= $(foreach inc_file, $(INC_FILE), -i$(inc_file))
LD_FLAG		= $(foreach ld_file, $(LD_FILE), -l$(ld_file))

COMPILER_OP	= -Wall -fPIC -O2  -rdynamic -g -funsigned-char -fstack-check -funroll-loops -fprefetch-loop-arrays -masm=att \
		  -malign-double -msse2 -minline-all-stringops -maccumulate-outgoing-args
SO_OP		= $(COMPILER_OP)
SO_OP		+= -shared

# $(TARGET) is an undefined variable, and it should be passed when invoking `make`.
OBJ		= $(TARGET)
SRC		= $(OBJ:=.c)
SO_OBJ		= $(OBJ).so
SO_SRC		= $(OBJ)_so.c

# Main entry of the make process.
all:deploy
	@echo "[INFO]Building finished."


$(OBJ):check_args
	$(C) $(COMPILER_OP) $(INC) $(LD) $(INC_FLAG) -o $(OBJ) $(SRC_DIR)/$(SRC) $(LD_FLAG)

$(SO_OBJ):check_args
	$(C) $(SO_OP) $(INC) $(LD) $(INC_FLAG) -o $(SO_OBJ) $(SRC_DIR)/$(SO_SRC) $(LD_FLAG)

test:
	$(C) $(COMPILER_OP) $(INC) $(LD) $(INC_FLAG) -o test $(SRC_DIR)/test.c $(LD_FLAG)

.PHONY:clean deploy chkargs check_dir check_target
check_dir:
	@if [ ! -d "$(OBJ_DIR)" ];then\
		mkdir $(OBJ_DIR);\
		fi
	@if [ ! -d "$(SO_DIR)" ];then\
		mkdir $(SO_DIR);\
		fi
	@if [ ! -d "$(SRC_DIR)" ];then\
		mkdir $(SRC_DIR);\
		fi
	@if [ ! -d "$(TMPL_DIR)" ];then\
		mkdir $(TMPL_DIR);\
		fi
	@for _dir in $(INC_DIR);\
		do\
		if [ ! -d "$$_dir" ];then\
			mkdir $$_dir;\
		fi;\
		done
	@for _dir in $(LIB_DIR);\
		do\
		if [ ! -d "$$_dir" ];then\
			mkdir $$_dir;\
		fi;\
		done

check_args:check_dir
	@if [ -z "$(OBJ)" ];then\
		echo "[WARNING]Please specify a TARGET to build: \r\nmake TARGET=obj [...]\r\n";\
		exit 1;\
	fi
	@if [ ! -f "$(SRC_DIR)/$(SRC)" ];then\
		echo "[ERROR]$(SRC_DIR)/$(SRC) not found.\r\n";\
		exit 1;\
	fi
	@if [ ! -f "$(SRC_DIR)/$(SO_SRC)" ];then\
		echo "[WARNING]$(SRC_DIR)/$(SO_SRC) not found.\r\n";\
	fi
	
deploy:$(OBJ) $(SO_OBJ)
	@if [ -d "$(SO_DIR)" -a -f "$(SO_OBJ)" ];then\
		mv ./$(SO_OBJ) $(SO_DIR)/;\
	fi
	@if [ -d "$(OBJ_DIR)" -a -f "$(OBJ)" ];then\
		mv ./$(OBJ) $(OBJ_DIR)/;\
	fi


clean:check_args
	@if [ -d "$(OBJ_DIR)" -a -f "$(OBJ_DIR)/$(OBJ)" ];then\
		cd $(OBJ_DIR) && rm $(OBJ);\
	fi
	@if [ -d  "$(SO_DIR)" -a -f "$(SO_DIR)/$(SO_OBJ)" ];then\
		cd $(SO_DIR) && rm $(SO_OBJ);\
	fi
	@if [ -d "$(LIB)" ];then\
		if [ -n "$(LIB_FILE)" ];then\
			cd $(LIB) && rm $(LIB_FILE);\
		fi;\
	fi
	@echo "[INFO]Cleaning finished."

